<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html>
<head>
<title>Zeichnen mit PyQt4</title>
<link rel="stylesheet" href="../format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="PyQt, PyQt4, tutorial, python, drawing, Linux">
<meta nam="description" content="Zeichnen mit PyQt4">
<meta name="language" content="de">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">
<meta name="translation" content="manuel stein">
</head>

<body>

<div class="content">


<a href="/" title="Home">Home</a>&nbsp;
<a href=".." title="Home">Contents</a>


<h1>Zeichnen mit PyQt4</h1>

<p>
Zeichnen wird für die Veränderung und Erweiterung eines bestehenden Widgets oder bei der
Erstellung eines bedarsangepassten, vollständig neu erzeugten Widgets verwendet. 
Zum Zeichnen nutzen wir die Zeichen-API, das das PyQt4-Toolkit mitbringt.
</p>

<p>
Das Zeichnen wird mittels der <em>paintEvent()</em>-Methode vollzogen. 
Der Zeichnen-Code wird zwischen der <em>begin()</em>- und <em>end()</em>-Methode 
des <em>QPainter</em>-Objekts platziert.
</p>

<h3>Das Zeichnen von Text</h3>

<p>
  Wir beginnen damit Unicode-Text in den Bereich des Fensters zu zeichnen.
</p>

<pre class="code">
#!/usr/bin/python

# drawtext.py

import sys
from PyQt4 import QtGui, QtCore


class DrawText(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('Draw Text')

        self.text = u'\u041b\u0435\u0432 \u041d\u0438\u043a\u043e\u043b\u0430\
\u0435\u0432\u0438\u0447 \u0422\u043e\u043b\u0441\u0442\u043e\u0439: \n\
\u0410\u043d\u043d\u0430 \u041a\u0430\u0440\u0435\u043d\u0438\u043d\u0430'



    def paintEvent(self, event):
        paint = QtGui.QPainter()
        paint.begin(self)
        paint.setPen(QtGui.QColor(168, 34, 3))
        paint.setFont(QtGui.QFont('Decorative', 10))
        paint.drawText(event.rect(), QtCore.Qt.AlignCenter, self.text)
        paint.end()


app = QtGui.QApplication(sys.argv)
dt = DrawText()
dt.show()
app.exec_()
</pre>

<p>
  In unserem Beispiel zeichnen wir etwas Text in Azbuka. Der Text 
wird senkrecht und waagerecht ausgerichtet.
</p>

<pre class="explanation">
 def paintEvent(self, event):
</pre>

<p>
Das Zeichnen selbst wird mit dem <em>paintEvent()</em> vollzogen.
</p>

<pre class="explanation">
 paint = QtGui.QPainter()
 paint.begin(self)
 ...
 paint.end()
</pre>

<p>
Die <em>QPainter</em>-Klasse ist für alles niedrigschwellige Malen verantwortlich. 
Alle Malmethoden liegen zwischen <em>begin()</em>- und <em>end()</em>-Methode.
</p>

<pre class="explanation">
 paint.setPen(QtGui.QColor(168, 34, 3))
 paint.setFont(QtGui.QFont('Decorative', 10))
</pre>

<p>
Hier definieren wir Stift und Schrifttyp, die wir zum Zeichen des Textes verwenden.
</p>

<pre class="explanation">
 paint.drawText(event.rect(), QtCore.Qt.AlignCenter, self.text)
</pre>

<p>
Die <em>drawText()</em>-Methode zeichnet den Text in das Fenster.
</p>

<img src="../images/drawtext.jpg" alt="Text zeichnen">
<p class="figure">Abbildung: Das Zeichnen von Text</p>


<h3>Punkte zeichnen</h3>

<p>
Ein Punkt ist das einfachste grafische Objekt, das man zeichnen kann. 
Es ist ein kleiner Punkt auf dem Fenster.
</p>

<pre class="code">
#!/usr/bin/python

# points.py

import sys, random
from PyQt4 import QtGui, QtCore


class Points(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('Points')

    def paintEvent(self, event):
        paint = QtGui.QPainter()
        paint.begin(self)
        paint.setPen(QtCore.Qt.red)
        size = self.size()
        for i in range(1000):
            x = random.randint(1, size.width()-1)
            y = random.randint(1, size.height()-1)
            paint.drawPoint(x, y)
        paint.end()

app = QtGui.QApplication(sys.argv)
dt = Points()
dt.show()
app.exec_()
</pre>

<p>
In unserem Beispiel zeichnen wir 1000 zufällig auf der Fläche verteilte rote Punkte.
</p>


<pre class="explanation">
 paint.setPen(QtCore.Qt.red)
</pre>

<p>
Wir belegen den Stift mit roter Farbe, in diesem Fall durch Verwendung 
einer vordefinierten Farbkonstanten (<em>Qt.red</em>).
</p>

<pre class="explanation">
 size = self.size()
</pre>

<p>
Bei jeder Größenänderung am Fenster wird ein paint-Ereignis ausgelöst. Die aktuelle Größe
eines Fensters erfragen wir mit der <em>size()</em>-Methode.
</p>

<pre class="explanation">
 paint.drawPoint(x, y)
</pre>

<p>
Wir zeichnen den Punkt mit der <em>drawPoint()</em>-Methode.
</p>

<img src="../images/points.jpg" alt="Punkte">
<p class="figure">Abbildung: Punkte</p>

<h3>Farben</h3>

<p>
Eine Farbe ist ein Objekt, das eine Kombination aus Rot-, Grün- und 
Blauintensitätswerten repräsentiert. Zulässige RGB-Werte liegen 
zwischen 0 und 255. Wir können eine Farbe auf verschiedene Weisen definieren. 
Die verbreitetsten sind RGB-Dezimalwerte oder -Hexadezimalwerte. Genauso lässt 
sich ein RGBA-Wert eingesetzt werden, das steht für Rot, Grün, Blau und Alpha, 
wodurch wir zusätzliche Information zur Transparenz hinzufügen können. 
Ein Alphawert von 255 steht für volle Farbe, 0 steht für vollständige 
Transparenz, d.h. die Farbe ist nicht sichtbar.
</p>

<pre class="code">
#!/usr/bin/python

# colors.py

import sys, random
from PyQt4 import QtGui, QtCore


class Colors(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.setGeometry(300, 300, 350, 280)
        self.setWindowTitle('Colors')

    def paintEvent(self, event):
        paint = QtGui.QPainter()
        paint.begin(self)

        color = QtGui.QColor(0, 0, 0)
        color.setNamedColor('#d4d4d4')
        paint.setPen(color)

        paint.setBrush(QtGui.QColor(255, 0, 0, 80))
        paint.drawRect(10, 15, 90, 60)

        paint.setBrush(QtGui.QColor(255, 0, 0, 160))
        paint.drawRect(130, 15, 90, 60)

        paint.setBrush(QtGui.QColor(255, 0, 0, 255))
        paint.drawRect(250, 15, 90, 60)

        paint.setBrush(QtGui.QColor(10, 163, 2, 55))
        paint.drawRect(10, 105, 90, 60)

        paint.setBrush(QtGui.QColor(160, 100, 0, 255))
        paint.drawRect(130, 105, 90, 60)

        paint.setBrush(QtGui.QColor(60, 100, 60, 255))
        paint.drawRect(250, 105, 90, 60)

        paint.setBrush(QtGui.QColor(50, 50, 50, 255))
        paint.drawRect(10, 195, 90, 60)

        paint.setBrush(QtGui.QColor(50, 150, 50, 255))
        paint.drawRect(130, 195, 90, 60)

        paint.setBrush(QtGui.QColor(223, 135, 19, 255))
        paint.drawRect(250, 195, 90, 60)

        paint.end()

app = QtGui.QApplication(sys.argv)
dt = Colors()
dt.show()
app.exec_()
</pre>

<p>
In unserem Beispiel zeichnen wir 9 farbige Rechtecke. Die erste Reihe zeigt 
rote Farbe in unterschiedlichen Alphaabstufungen.
</p>

<pre class="explanation">
 color = QtGui.QColor(0, 0, 0)
 color.setNamedColor('#d4d4d4')
</pre>

<p>
Hier definieren wir eine Farbe in Hexadezimal-Schreibweise.
</p>


<pre class="explanation">
 paint.setBrush(QtGui.QColor(255, 0, 0, 80));
 paint.drawRect(10, 15, 90, 60)
</pre>

<p>
Hier definieren wir einen Pinsel und zeichnen ein Rechteck. Ein <em>Pinsel</em> 
ist ein elementares Grafikobjekt, um den Hintergrund einer Figur zu zeichnen. 
Die <em>drawRect()</em>-Methode empfängt vier Parameter. Die ersten zwei sind x- und y-Werte. 
Der dritte und vierte Parameter sind Breite und Höhe des Rechtecks. Die Methode zeichnet ein 
Rechteck unter Verwendung des eingestellten Stifts und des eingestellten Pinsels.
</p>


<img src="../images/colors.jpg" alt="Farben">
<p class="figure">Abbildung: Farben</p>


<h3>QPen</h3>

<p>
<em>QPen</em> ist ein grundlegendes Grafikobjekt. Es wird zum Zeichnen von Linien,
Kurven und Umrandungen eines Rechtecks, Ellipsen, Polygonen oder anderen Formen verwendet.
</p>

<pre class="code">
#!/usr/bin/python

# penstyles.py

import sys
from PyQt4 import QtGui, QtCore


class PenStyles(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.setGeometry(300, 300, 280, 270)
        self.setWindowTitle('penstyles')

    def paintEvent(self, event):
        paint = QtGui.QPainter()

        paint.begin(self)

        pen = QtGui.QPen(QtCore.Qt.black, 2, QtCore.Qt.SolidLine)

        paint.setPen(pen)
        paint.drawLine(20, 40, 250, 40)

        pen.setStyle(QtCore.Qt.DashLine)
        paint.setPen(pen)
        paint.drawLine(20, 80, 250, 80)

        pen.setStyle(QtCore.Qt.DashDotLine)
        paint.setPen(pen)
        paint.drawLine(20, 120, 250, 120)

        pen.setStyle(QtCore.Qt.DotLine)
        paint.setPen(pen)
        paint.drawLine(20, 160, 250, 160)

        pen.setStyle(QtCore.Qt.DashDotDotLine)
        paint.setPen(pen)
        paint.drawLine(20, 200, 250, 200)

        pen.setStyle(QtCore.Qt.CustomDashLine)
        pen.setDashPattern([1, 4, 5, 4])
        paint.setPen(pen)
        paint.drawLine(20, 240, 250, 240)

        paint.end()

app = QtGui.QApplication(sys.argv)
dt = PenStyles()
dt.show()
app.exec_()
</pre>

<p>
In unserem Beispiel zeichnen wir sechs Linien. Die Linien werden in sechs unterschiedlichen 
Stiftstilen nachgezogen. Es gibt fünf vordefinierte Stiftstile. Darüber hinaus können wir 
benutzerdefinierte Stile erstellen. Mit einem solchen wird die letzte Linie gezeichnet.
</p>

<pre class="explanation">
 pen = QtGui.QPen(QtCore.Qt.black, 2, QtCore.Qt.SolidLine)
</pre>

<p>
Wir erzeugen ein <em>QPen</em>-Objekt in schwarzer Farbe. Die Breite wird auf zwei 
Pixel gesetzt, sodass wir sehen den Unterschied zwischen den Stiftstilen sehen können. 
Die <em>QtCore.Qt.SolidLine</em> ist einer der vordefinierten Stile.
</p>

<pre class="explanation">
 pen.setStyle(QtCore.Qt.CustomDashLine)
 pen.setDashPattern([1, 4, 5, 4])
 paint.setPen(pen)
</pre>

<p>
Hier bestimmen wir einen benutzerdefinierten Stiftstil. Wir wählen einen 
<em>QtCore.QtCustomDashLine</em>-Stiftstil und erzeugen mit der 
<em>setDashPattern()</em>-Methode eine gestrichelte Linie. Die Ziffernliste 
definiert einen Stil. Es muss eine gerade Anzahl an Ziffern sein. Ungerade 
Ziffern definieren einen Strich, gerade Ziffern eine die Größe der Lücken. 
Je größer die Ziffern, desto größer Abstand oder Linie. Unser Muster 
ist 1px Strich, 4px Lücke, 5px Strich und 4px Lücke <acronym title="et cetera">etc</acronym>.
</p>

<img src="../images/penstyles.jpg" alt="Stiftstile">
<p class="figure">Abbildung: Stiftstile </p>


<h3>QBrush</h3>

<p>
<em>QBrush</em> ist ein grundlegendes Grafikobjekt. Es wird zum Malen des Hintergrundes
von Figuren wie Rechtecke, Ellipsen oder Polygone verwendet. 
Es gibt drei Pinseltypen: Vordefinierte Pinsel, Verläufe oder Texturmuster.
</p>

<pre class="code">
#!/usr/bin/python

# brushes.py

import sys
from PyQt4 import QtGui, QtCore


class Brushes(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.setGeometry(300, 300, 355, 280)
        self.setWindowTitle('Brushes')

    def paintEvent(self, event):
        paint = QtGui.QPainter()

        paint.begin(self)

        brush = QtGui.QBrush(QtCore.Qt.SolidPattern)
        paint.setBrush(brush)
        paint.drawRect(10, 15, 90, 60)

        brush.setStyle(QtCore.Qt.Dense1Pattern)
        paint.setBrush(brush)
        paint.drawRect(130, 15, 90, 60)

        brush.setStyle(QtCore.Qt.Dense2Pattern)
        paint.setBrush(brush)
        paint.drawRect(250, 15, 90, 60)

        brush.setStyle(QtCore.Qt.Dense3Pattern)
        paint.setBrush(brush)
        paint.drawRect(10, 105, 90, 60)

        brush.setStyle(QtCore.Qt.DiagCrossPattern)
        paint.setBrush(brush)
        paint.drawRect(10, 105, 90, 60)

        brush.setStyle(QtCore.Qt.Dense5Pattern)
        paint.setBrush(brush)
        paint.drawRect(130, 105, 90, 60)

        brush.setStyle(QtCore.Qt.Dense6Pattern)
        paint.setBrush(brush)
        paint.drawRect(250, 105, 90, 60)

        brush.setStyle(QtCore.Qt.HorPattern)
        paint.setBrush(brush)
        paint.drawRect(10, 195, 90, 60)

        brush.setStyle(QtCore.Qt.VerPattern)
        paint.setBrush(brush)
        paint.drawRect(130, 195, 90, 60)

        brush.setStyle(QtCore.Qt.BDiagPattern)
        paint.setBrush(brush)
        paint.drawRect(250, 195, 90, 60)

        paint.end()

app = QtGui.QApplication(sys.argv)
dt = Brushes()
dt.show()
app.exec_()
</pre>

<p>
In unserem Beispiel zeichen wir sechs verschiedene Rechtecke.
</p>

<pre class="explanation">
 brush = QtGui.QBrush(QtCore.Qt.SolidPattern)
 paint.setBrush(brush)
 paint.drawRect(10, 15, 90, 60)
</pre>

<p>
Wir definieren ein Pinselobjekt, übergeben es dem paint-Objekt und zeichnen ein Rechteck 
durch Aufruf der <em>drawRect()</em>-Methode.
</p>

<img src="../images/brushes.png" alt="Pinsel">
<p class="figure">Abbildung: Pinsel</p>

<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified September 12, 2007  <span class="copyright">&copy; 2007 - 2011 Jan Bodnar</span>
<span class="copyright">Translation © 2009 Manuel Stein</span>
</div>
</div>

</div> <!-- content -->
</body>
</html>

